←Select platform

ReadBarcodes(RasterImage,LeadRect,int,BarcodeSymbology[],BarcodeReadOptions[]) Method

Summary
Read multiple barcodes from an image with symbologies from a specified group and options.
Syntax
C#
VB
Objective-C
C++
Java
Public Overloads Function ReadBarcodes( _ 
   ByVal image As RasterImage, _ 
   ByVal searchBounds As LeadRect, _ 
   ByVal maximumBarcodes As Integer, _ 
   ByVal symbologies() As BarcodeSymbology, _ 
   ByVal options() As BarcodeReadOptions _ 
) As BarcodeData() 
- (nullable NSArray<LTBarcodeData *> *)readBarcodes:(LTRasterImage *)image  
                                       searchBounds:(LeadRect)searchBounds  
                                    maximumBarcodes:(NSUInteger)maximumBarcodes  
                                        symbologies:(nullable NSArray<NSNumber *> *)symbologies  
                                            options:(nullable NSArray<LTBarcodeReadOptions *> *)options  
                                              error:(NSError **)error 
public BarcodeData[] readBarcodes( 
  RasterImage image,  
  LeadRect searchBounds,  
  int maximumBarcodes,  
  BarcodeSymbology[] symbologies,  
  BarcodeReadOptions[] options 
) 

Parameters

image
A RasterImage object that contains the image data. Must not be null (Nothing in VB).

searchBounds
A LeadRect that specifies the region of interest area in the image where the barcodes search and detection is performed. You can specify LeadRect.Empty to indicate that the search must be performed on the whole image.

maximumBarcodes
An Int32 that specifies the maximum number of barcodes to return. Must be a value greater than or equal to 0. The value of 0 means all barcodes.

symbologies
An array of BarcodeSymbology enumeration members that specifies the barcode symbologies (types) to search for.

options
An array of BarcodeReadOptions that specifies the options to use. This can be null (Nothing in VB), where the current default options is used. Otherwise, the method will use the options that corresponds to the symbologies being read, if the array does not contain specific options for a symbologies being read, then the default version will be used.

Return Value

An array of BarcodeData objects or derived classes that contains the symbology, data, location and any rotation angle for each barcode found. If no barcodes can be found, then this method will return an empty array (Length equals to 0).

Remarks

Use this method if you want to read multiple barcodes of the same or multiple symbologies from an image. For example, to read all UPC and QR barcodes in the image, use an array of BarcodeSymbology.UPC-A, BarcodeSymbology.UPC-E and BarcodeSymbology.QR.

LEADTOOLS barcode read engine is optimized for speed and can search for multiple similar symbologies at the same time. This method simply returns the first barcode that is detected correctly using the symbologies and current options.

The ReadSymbology event will occur before and after attempting to read any symbology. The read options being used whether the default or specified will be set in the BarcodeReadSymbologyEventArgs.Options property of the event data.

If symbologies is null (Nothing in VB), then this method will use all the currently available symbologies. If this parameter contains an empty array, then no barcode will be detected and an empty array will be returned.

The BarcodeReader provides the following barcode read methods:

Method Description
ReadBarcode(RasterImage image, LeadRect searchBounds, BarcodeSymbology symbology) and ReadBarcode(RasterImage image, LeadRect searchBounds, BarcodeSymbology symbology, BarcodeReadOptions options)

Read one barcode from an image with specified symbology and default or specific options. Use these methods if you want to read a single barcode from the image, for example, a QR symbol by specifying BarcodeSymbology.QR or if you want to read any barcode found regardless of its type by using BarcodeSymbology.Unknown.

ReadBarcode(RasterImage image, LeadRect searchBounds, BarcodeSymbology[] symbologies) and ReadBarcode(RasterImage image, LeadRect searchBounds, BarcodeSymbology[] symbologies, BarcodeReadOptions[] options)

Read one barcode from an image with a symbology from a specified group and default or specific options. Use these methods if you want to read a single barcode from a known group. For example, to read a barcode that can be of any UPC type, pass an array of BarcodeSymbology.UPCA and BarcodeSymbology.UPCE.

ReadBarcodes(RasterImage image, LeadRect searchBounds, int maximumBarcodes, BarcodeSymbology[] symbologies) and ReadBarcodes(RasterImage image, LeadRect searchBounds, int maximumBarcodes, BarcodeSymbology[] symbologies, BarcodeReadOptions[] options)

Read multiple barcodes from an image with symbologies from a specified group and default or specific options. Use these methods if you want to read multiple barcodes of the same or multiple symbologies.

Example

This example creates two threads: One for reading horizontal barcodes and one for reading vertical barcodes. Then it uses the same BarcodeReader to try and read all the barcodes from an image using both threads

C#
VB
using Leadtools; 
using Leadtools.Codecs; 
using Leadtools.Barcode; 
using Leadtools.ImageProcessing; 
 
 
// This class holds the data we will pass to each thread 
public class MyThreadData 
{ 
	// This worker thread name 
	public string Name; 
 
	// Barcode reader instance 
	public BarcodeReader BarcodeReaderInstance; 
 
	// Array of options to use 
	public BarcodeReadOptions[] ReadOptions; 
 
	// Image file containing the barcodes 
	public string ImageFileName; 
 
	// This will hold the barcodes found 
	public BarcodeData[] Barcodes; 
 
	// In case of errors 
	public Exception Error; 
 
	// Event to notify when the thread is finished 
	public ManualResetEvent FinishedEvent; 
} 
 
		public void BarcodeReader_ReadBarcodeExample6() 
{ 
	string[] imageFileNames = PrepareImages(); 
 
	// Create a Barcode engine 
	BarcodeEngine engine = new BarcodeEngine(); 
 
	// Get the Barcode reader instance 
	BarcodeReader reader = engine.Reader; 
 
	// Get a version of all read options that support rotated barcodes 
	BarcodeReadOptions[] verticalBarcodeReadOptions = GetVerticalReadBarcodeOptions(reader); 
 
	// Synchronization events 
	ManualResetEvent[] finishedEvents = new ManualResetEvent[2]; 
 
	// Create the thread data objects 
	MyThreadData[] threadsData = new MyThreadData[2]; 
	for (int i = 0; i < threadsData.Length; i++) 
	{ 
		finishedEvents[i] = new ManualResetEvent(false); 
 
		threadsData[i] = new MyThreadData(); 
		threadsData[i].BarcodeReaderInstance = reader; 
		threadsData[i].ReadOptions = null; 
		threadsData[i].FinishedEvent = finishedEvents[i]; 
	} 
 
	// Setup the read options for the two threads 
	threadsData[0].Name = "Read Default Options Thread"; 
	threadsData[0].ReadOptions = null;  // Default, or horizontal 
	threadsData[1].Name = "Read Vertical Barcodes Thread"; 
	threadsData[1].ReadOptions = verticalBarcodeReadOptions; 
 
	List<BarcodeData> totalBarcodes = new List<BarcodeData>(); 
 
	// Now loop through all the images and try to read the barcodes with both threads at the same time 
	foreach (string imageFileName in imageFileNames) 
	{ 
		Console.WriteLine("Reading barcodes from {0}", imageFileName); 
 
		for (int i = 0; i < 2; i++) 
		{ 
			// Clear the previous results (if any), set up the file name and run 
			threadsData[i].Barcodes = null; 
			threadsData[i].Error = null; 
			threadsData[i].ImageFileName = imageFileName; 
			ThreadPool.QueueUserWorkItem(new WaitCallback(ReadBarcodesInThread), threadsData[i]); 
		} 
 
		// Wait till all the threads finishes 
		foreach (ManualResetEvent waitHandle in finishedEvents) 
			waitHandle.WaitOne(); 
 
		// Add the barcodes found to our list 
		for (int i = 0; i < 2; i++) 
		{ 
			if (threadsData[i].Error != null) 
			{ 
				Console.WriteLine("{0} had error {1}", threadsData[i].Name, threadsData[i].Error); 
			} 
			else if (threadsData[i].Barcodes != null) 
			{ 
				totalBarcodes.AddRange(threadsData[i].Barcodes); 
			} 
		} 
	} 
 
	// We are done, show the total number of barcodes read 
	Console.WriteLine("Done. Total barcodes read: {0}", totalBarcodes.Count); 
} 
 
private static void ReadBarcodesInThread(object state) 
{ 
	MyThreadData threadData = state as MyThreadData; 
 
	Console.WriteLine("{0} is reading the barcodes", threadData.Name); 
 
	try 
	{ 
		// Load the image 
		using (RasterCodecs codecs = new RasterCodecs()) 
		{ 
			using (RasterImage image = codecs.Load(threadData.ImageFileName, 0, CodecsLoadByteOrder.BgrOrGray, 1, 1)) 
			{ 
				// Read the barcodes using our options 
				threadData.Barcodes = threadData.BarcodeReaderInstance.ReadBarcodes(image, LeadRect.Empty, 0, null, threadData.ReadOptions); 
			} 
		} 
 
		Console.WriteLine("{0} has read {1} barcodes", threadData.Name, threadData.Barcodes.Length); 
	} 
	catch (Exception ex) 
	{ 
		// Return the error to main 
		threadData.Error = ex; 
	} 
	finally 
	{ 
		// Tell main we are done 
		threadData.FinishedEvent.Set(); 
	} 
} 
 
private static string[] PrepareImages() 
{ 
	// Create a 90 degrees rotated version of Barcode1.tif 
 
	string originalImageFileName = Path.Combine(LEAD_VARS.ImagesDir, "Barcode1.tif"); 
	string rotatedImageFileName = Path.Combine(LEAD_VARS.ImagesDir, "Barcode1_Rotated90.tif"); 
 
	using (RasterCodecs codecs = new RasterCodecs()) 
	{ 
		using (RasterImage image = codecs.Load(originalImageFileName, 0, CodecsLoadByteOrder.BgrOrGray, 1, 1)) 
		{ 
			RotateCommand rotate = new RotateCommand(90 * 100, RotateCommandFlags.Resize, RasterColor.FromKnownColor(RasterKnownColor.White)); 
			rotate.Run(image); 
 
			codecs.Save(image, rotatedImageFileName, RasterImageFormat.CcittGroup4, 1); 
		} 
	} 
 
	return new string[] { originalImageFileName, rotatedImageFileName }; 
} 
 
private static BarcodeReadOptions[] GetVerticalReadBarcodeOptions(BarcodeReader reader) 
{ 
	// By default, the options read horizontal barcodes only, create an array of options capable of reading vertical barcodes 
 
	// Notice, we cloned the default options in reader so we will not change the original options 
 
	OneDBarcodeReadOptions oneDReadOptions = reader.GetDefaultOptions(BarcodeSymbology.UPCA).Clone() as OneDBarcodeReadOptions; 
	oneDReadOptions.SearchDirection = BarcodeSearchDirection.Vertical; 
 
	FourStateBarcodeReadOptions fourStateReadOptions = reader.GetDefaultOptions(BarcodeSymbology.USPS4State).Clone() as FourStateBarcodeReadOptions; 
	fourStateReadOptions.SearchDirection = BarcodeSearchDirection.Vertical; 
 
	PostNetPlanetBarcodeReadOptions postNetPlanetReadOptions = reader.GetDefaultOptions(BarcodeSymbology.PostNet).Clone() as PostNetPlanetBarcodeReadOptions; 
	postNetPlanetReadOptions.SearchDirection = BarcodeSearchDirection.Vertical; 
 
	GS1DatabarStackedBarcodeReadOptions gs1StackedReadOptions = reader.GetDefaultOptions(BarcodeSymbology.GS1DatabarStacked).Clone() as GS1DatabarStackedBarcodeReadOptions; 
	gs1StackedReadOptions.SearchDirection = BarcodeSearchDirection.Vertical; 
 
	PatchCodeBarcodeReadOptions patchCodeReadOptions = reader.GetDefaultOptions(BarcodeSymbology.PatchCode).Clone() as PatchCodeBarcodeReadOptions; 
	patchCodeReadOptions.SearchDirection = BarcodeSearchDirection.Vertical; 
 
	PDF417BarcodeReadOptions pdf417ReadOptions = reader.GetDefaultOptions(BarcodeSymbology.PDF417).Clone() as PDF417BarcodeReadOptions; 
	pdf417ReadOptions.SearchDirection = BarcodeSearchDirection.Vertical; 
 
	MicroPDF417BarcodeReadOptions microPdf417ReadOptions = reader.GetDefaultOptions(BarcodeSymbology.MicroPDF417).Clone() as MicroPDF417BarcodeReadOptions; 
	microPdf417ReadOptions.SearchDirection = BarcodeSearchDirection.Vertical; 
 
	// Even though this array will not contain all options, it should be enough to read all barcodes, since the version of ReadBarcodes we will use 
	// will use the default options if an overriden is not passed 
	BarcodeReadOptions[] readOptions = 
	{ 
	oneDReadOptions, fourStateReadOptions, postNetPlanetReadOptions, gs1StackedReadOptions, patchCodeReadOptions, pdf417ReadOptions, microPdf417ReadOptions 
 }; 
 
	return readOptions; 
} 
 
 
 
static class LEAD_VARS 
{ 
   public const string ImagesDir = @"C:\LEADTOOLS21\Resources\Images"; 
} 
Imports Leadtools 
Imports Leadtools.Codecs 
Imports Leadtools.Barcode 
Imports Leadtools.ImageProcessing 
 
' This class holds the data we will pass to each thread 
 
Public Class MyThreadData 
   ' This worker thread name 
   Public Name As String 
 
   ' Barcode reader instance 
   Public BarcodeReaderInstance As BarcodeReader 
 
   ' Array of options to use 
   Public ReadOptions As BarcodeReadOptions() 
 
   ' Image file containing the barcodes 
   Public ImageFileName As String 
 
   ' This will hold the barcodes found 
   Public Barcodes As BarcodeData() 
 
   ' In case of errors 
   Public [Error] As Exception 
 
   ' Event to notify when the thread is finished 
   Public FinishedEvent As ManualResetEvent 
End Class 
 
Public Sub BarcodeReader_ReadBarcodeExample6() 
   Dim imageFileNames As String() = PrepareImages() 
 
   ' Create a Barcode engine 
   Dim engine As New BarcodeEngine() 
 
   ' Get the Barcode reader instance 
   Dim reader As BarcodeReader = engine.Reader 
 
   ' Get a version of all read options that support rotated barcodes 
   Dim verticalBarcodeReadOptions As BarcodeReadOptions() = GetVerticalReadBarcodeOptions(reader) 
 
   ' Synchronization events 
   Dim finishedEvents As ManualResetEvent() = New ManualResetEvent(1) {} 
 
   ' Create the thread data objects 
   Dim threadsData As MyThreadData() = New MyThreadData(1) {} 
   For i As Integer = 0 To threadsData.Length - 1 
      finishedEvents(i) = New ManualResetEvent(False) 
 
      threadsData(i) = New MyThreadData() 
      threadsData(i).BarcodeReaderInstance = reader 
      threadsData(i).ReadOptions = Nothing 
      threadsData(i).FinishedEvent = finishedEvents(i) 
   Next 
 
   ' Setup the read options for the two threads 
   threadsData(0).Name = "Read Default Options Thread" 
   threadsData(0).ReadOptions = Nothing 
   ' Default, or horizontal 
   threadsData(1).Name = "Read Vertical Barcodes Thread" 
   threadsData(1).ReadOptions = verticalBarcodeReadOptions 
 
   Dim totalBarcodes As New List(Of BarcodeData)() 
 
   ' Now loop through all the images and try to read the barcodes with both threads at the same time 
   For Each imageFileName As String In imageFileNames 
      Console.WriteLine("Reading barcodes from {0}", imageFileName) 
 
      For i As Integer = 0 To 1 
         ' Clear the previous results (if any), set up the file name and run 
         threadsData(i).Barcodes = Nothing 
         threadsData(i).[Error] = Nothing 
         threadsData(i).ImageFileName = imageFileName 
         ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf ReadBarcodesInThread), threadsData(i)) 
      Next 
 
      ' Wait till all the threads finishes 
      For Each waitHandle As ManualResetEvent In finishedEvents 
         waitHandle.WaitOne() 
      Next 
 
      ' Add the barcodes found to our list 
      For i As Integer = 0 To 1 
         If threadsData(i).[Error] IsNot Nothing Then 
            Console.WriteLine("{0} had error {1}", threadsData(i).Name, threadsData(i).[Error]) 
         ElseIf threadsData(i).Barcodes IsNot Nothing Then 
            totalBarcodes.AddRange(threadsData(i).Barcodes) 
         End If 
      Next 
   Next 
 
   ' We are done, show the total number of barcodes read 
   Console.WriteLine("Done. Total barcodes read: {0}", totalBarcodes.Count) 
End Sub 
 
Private Shared Sub ReadBarcodesInThread(state As Object) 
   Dim threadData As MyThreadData = TryCast(state, MyThreadData) 
 
   Console.WriteLine("{0} is reading the barcodes", threadData.Name) 
 
   Try 
      ' Load the image 
      Using codecs As New RasterCodecs() 
         Using image As RasterImage = codecs.Load(threadData.ImageFileName, 0, CodecsLoadByteOrder.BgrOrGray, 1, 1) 
            ' Read the barcodes using our options 
            threadData.Barcodes = threadData.BarcodeReaderInstance.ReadBarcodes(image, LeadRect.Empty, 0, Nothing, threadData.ReadOptions) 
         End Using 
      End Using 
 
      Console.WriteLine("{0} has read {1} barcodes", threadData.Name, threadData.Barcodes.Length) 
   Catch ex As Exception 
      ' Return the error to main 
      threadData.[Error] = ex 
   Finally 
      ' Tell main we are done 
      threadData.FinishedEvent.[Set]() 
   End Try 
End Sub 
 
Private Shared Function PrepareImages() As String() 
   ' Create a 90 degrees rotated version of Barcode1.tif 
 
   Dim originalImageFileName As String = Path.Combine(LEAD_VARS.ImagesDir, "Barcode1.tif") 
   Dim rotatedImageFileName As String = Path.Combine(LEAD_VARS.ImagesDir, "Barcode1_Rotated90.tif") 
 
   Using codecs As New RasterCodecs() 
      Using image As RasterImage = codecs.Load(originalImageFileName, 0, CodecsLoadByteOrder.BgrOrGray, 1, 1) 
         Dim rotate As New RotateCommand(90 * 100, RotateCommandFlags.Resize, RasterColor.FromKnownColor(RasterKnownColor.White)) 
         rotate.Run(image) 
 
         codecs.Save(image, rotatedImageFileName, RasterImageFormat.CcittGroup4, 1) 
      End Using 
   End Using 
 
   Return New String() {originalImageFileName, rotatedImageFileName} 
End Function 
 
Private Shared Function GetVerticalReadBarcodeOptions(reader As BarcodeReader) As BarcodeReadOptions() 
   ' By default, the options read horizontal barcodes only, create an array of options capable of reading vertical barcodes 
 
   ' Notice, we cloned the default options in reader so we will not change the original options 
 
   Dim oneDReadOptions As OneDBarcodeReadOptions = TryCast(reader.GetDefaultOptions(BarcodeSymbology.UPCA).Clone(), OneDBarcodeReadOptions) 
   oneDReadOptions.SearchDirection = BarcodeSearchDirection.Vertical 
 
   Dim fourStateReadOptions As FourStateBarcodeReadOptions = TryCast(reader.GetDefaultOptions(BarcodeSymbology.USPS4State).Clone(), FourStateBarcodeReadOptions) 
   fourStateReadOptions.SearchDirection = BarcodeSearchDirection.Vertical 
 
   Dim postNetPlanetReadOptions As PostNetPlanetBarcodeReadOptions = TryCast(reader.GetDefaultOptions(BarcodeSymbology.PostNet).Clone(), PostNetPlanetBarcodeReadOptions) 
   postNetPlanetReadOptions.SearchDirection = BarcodeSearchDirection.Vertical 
 
   Dim gs1StackedReadOptions As GS1DatabarStackedBarcodeReadOptions = TryCast(reader.GetDefaultOptions(BarcodeSymbology.GS1DatabarStacked).Clone(), GS1DatabarStackedBarcodeReadOptions) 
   gs1StackedReadOptions.SearchDirection = BarcodeSearchDirection.Vertical 
 
   Dim patchCodeReadOptions As PatchCodeBarcodeReadOptions = TryCast(reader.GetDefaultOptions(BarcodeSymbology.PatchCode).Clone(), PatchCodeBarcodeReadOptions) 
   patchCodeReadOptions.SearchDirection = BarcodeSearchDirection.Vertical 
 
   Dim pdf417ReadOptions As PDF417BarcodeReadOptions = TryCast(reader.GetDefaultOptions(BarcodeSymbology.PDF417).Clone(), PDF417BarcodeReadOptions) 
   pdf417ReadOptions.SearchDirection = BarcodeSearchDirection.Vertical 
 
   Dim microPdf417ReadOptions As MicroPDF417BarcodeReadOptions = TryCast(reader.GetDefaultOptions(BarcodeSymbology.MicroPDF417).Clone(), MicroPDF417BarcodeReadOptions) 
   microPdf417ReadOptions.SearchDirection = BarcodeSearchDirection.Vertical 
 
   ' Even though this array will not contain all options, it should be enough to read all barcodes, since the version of ReadBarcodes we will use 
   ' will use the default options if an overriden is not passed 
   Dim readOptions As BarcodeReadOptions() = {oneDReadOptions, fourStateReadOptions, postNetPlanetReadOptions, gs1StackedReadOptions, patchCodeReadOptions, pdf417ReadOptions, 
      microPdf417ReadOptions} 
 
   Return readOptions 
End Function 
 
Public NotInheritable Class LEAD_VARS 
   Public Const ImagesDir As String = "C:\LEADTOOLS21\Resources\Images" 
End Class 
Requirements

Target Platforms

Help Version 21.0.2021.7.2
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2021 LEAD Technologies, Inc. All Rights Reserved.

Leadtools.Barcode Assembly
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2021 LEAD Technologies, Inc. All Rights Reserved.